//framework example 1
//shows how to initialse the system, leave us in a graphical state with all the drawing buffers and system set up
//and initialises the timer loop to control our game
#include "../../../axl_framework.h"	//this opens axl_config.h for us

using namespace AXL_Projects;
//main game variables
static Framework* GameFramework;

//forward declarations to avoid having a header file

//after initialisation but before the game loop
void GameStartup();
//after game loop and Exit event but before allegro/framework has finished

//our logic code during the frame loop - paired with drawing
bool LogicGame();
bool LogicIntro();
bool LogicMenu();
bool LogicExit();

//our drawing code during the frame loop - paired with logic
bool DrawingGame();
bool DrawingIntro();
bool DrawingMenu();
bool DrawingExit();

//our override - allows branching out if we want to have lots of clean small functions 
//rather than lots of switch statements
bool OverrideLogic();
bool OverrideDrawing();

int position=0;	//test variable

int main(void)
{
	//create our framework, no animations to load
	//this will load up the configuration file (no animation file to load)
	//this constructor does not initialise allegro, we need to start it ourselves
	//it is like this so that we can make changes to the loaded config data before allegro starts
	//e.g. we might not want people to change the width/height of the screen
	//automatic starting is only available when the constructor supplying both config and animation/graphics xml files is called
	
	std::string config;
	
	config="config.xml";
	//to change to use embedded XML, change to something like:
	/*
	config="<?xml version=\"1.0\" encoding=\"UTF-8\" ?>"
	"<config>"
	    "<system fps=\"60\" debugon=\"1\" autowritemain=\"1\" autowritecustom=\"1\" enablejoystick=\"0\" enablekeyboard=\"1\" enablemouse=\"1\" enablesound=\"1\" enablemidi=\"1\" matchrefreshrate=\"0\" />"
	    "<graphics vsync=\"0\" graphicsmode=\"0\" depthpreferred=\"32\" depthfallback=\"16\" />"
	    "<window width=\"800\" height=\"600\" autodetect=\"windowed\" />"
	    "<sound maxvoicearray=\"32\" samplevolume=\"150\" musicvolume=\"128\" />"
	    "<custom name=\"author\" valuestring=\"Buffer Neil\" />"
	    "<custom name=\"badger\" valuestring=\"badger badger badger\" />"
	    "<custom name=\"game\" valuestring=\"turnips from space\" />"
	    "<custom name=\"score\" valueint=\"3\" />"
	    "<custom name=\"gravity\" valuefloat=\"-9.800000\" />"
	"</config>";
	*/
	GameFramework=new Framework(config,"");

	if(Configuration::GlobalErrorString!="")
	{
		delete GameFramework;
		allegro_message(Configuration::GlobalErrorString.c_str());
	}
	else
	{
		//start up allegro
		GameStartup();

		//run the timer loop, passing in all our functions that we have written to do logic/drawing
		//the first function pair in the list (LogicIntro) will be called by the framework, controlled by a FPS timer
		//in effect we would code assuming that this is called once per frame
		//the startgameloop method is only exited when ESCape is pressed
		if( !GameFramework->StartGameLoop(
				LogicIntro,DrawingIntro,
				LogicMenu,DrawingMenu,
				LogicGame,DrawingGame,
				LogicExit,DrawingExit,true) 
		) 
		{
			//error
			//GameFramework->DestroyFramework();
			delete GameFramework;
			allegro_message("Failed to run game loop. Check config.log");
		}
		else 
		{
			//no game end code as we may be using paging/triple buffering
			//and for that you need to flip pages, etc. and that code is only in 
			//the main timer loop or we would have to code it ourselves using the supplied buffers
			//GameEnd();
			//GameFramework->DestroyFramework();

			//shut down the system nicely, freeing up all memory
			delete GameFramework;
			allegro_message("Termination of Program ok. Check config.log");
		}
	}
	allegro_exit();
	return 0;
}
END_OF_MAIN();

void GameStartup()
{
	//this is called before the game loop was started
	//initialise once only stuff, e.g. animation library
	//then set timer type to the next logic entry
	clear_keybuf();
	//our default starting point is INTRO
	GameFramework->ChangeTimerType(GAME_INTRO);
	GameFramework->MsgBox("Simulates a full timer based game","Press SPACE to enter main game loop");
	readkey();
	clear_to_color(GameFramework->DrawingSurface,makecol(0,0,0));
	position=20;
}

bool LogicIntro()
{
	//if 1 key pressed, continue to next stage
	//all that is needed to change logic/drawing functions is to call changetimertype.
	//this simply changes the function pointer to use inside it's timer loop
	if(key[KEY_1])
	{
		GameFramework->ChangeTimerType(GAME_MENU);
		position+=10;
	}

	//loop continues, unless ESCape pressed
	return false;
}

bool DrawingIntro()
{
	//this is the drawing half of the pair. DrawingSurface is the drawing buffer provided by the framework
	//the framework handles all the page flipping, triple buffering, etc. if it is being used
	textprintf_ex(GameFramework->DrawingSurface, font, 0,position, makecol(255,0,0),-1, "In timer logic/drawing loop INTRO. press 1");
	return false;
}

bool LogicMenu()
{
	//when in this part we are told to press 2 to continue
	//we can also press X for a laugh, in order to restart graphics system
	if(key[KEY_X]) GameFramework->RestartSystem();
	if(key[KEY_2])
	{
		position+=10;
		GameFramework->ChangeTimerType(GAME_GAME);
	}
	return false;
}

bool DrawingMenu()
{
	textprintf_ex(GameFramework->DrawingSurface, font, 0,position, makecol(255,0,0),-1, "In timer logic/drawing loop MENU. press 2 (or X to try reset)");
	return false;
}

bool LogicGame()
{
	static bool TestedOverride=false;
	if(key[KEY_3])
	{
		position+=10;
		//call the override to show it working then on exit will start again from here
		if(!TestedOverride)
		{
			GameFramework->SetAutoGameLoopOverride(OverrideLogic,OverrideDrawing);
			TestedOverride=true;
		}
		else
			GameFramework->ChangeTimerType(GAME_EXIT);
	}

	return false;
}

bool DrawingGame()
{
	textprintf_ex(GameFramework->DrawingSurface, font, 0,position, makecol(255,0,0),-1, "In timer logic/drawing loop GAME. press 3");
	return false;
}

bool LogicExit()
{
	if(key[KEY_4])
	{
		position+=10;
		return true;
	}
	return false;
}

bool DrawingExit()
{
	textprintf_ex(GameFramework->DrawingSurface, font, 0,position, makecol(255,0,0),-1, "In timer logic/drawing loop EXIT. press 4 to quit");
	return false;
}

//this shows how you would override the current drawing/logic functions temporarily
//handy if we wish to change to a big chunk of code (e.g. an ingame pause or options menu)
//but dont want to put lots of code with conditional statements inside a function
bool OverrideLogic()
{
	//if returning true it will not exit game, but revert to normal
	//as this is called from the overrride
	//alternatively call auto override with NULL, it doesn't matter
	if(key[KEY_8])
	{
		position+=10;
		return true;
		//GameFramework->SetAutoGameLoopOverride(NULL,NULL);
	}
	return false;
}
bool OverrideDrawing()
{
	textprintf_ex(GameFramework->DrawingSurface, font, 30,position, makecol(128,255,0),-1, "*****OVERRIDE MODE. press 8 to return to normal");
	return false;
}
